import 'dart:convert';
import 'dart:isolate';
import 'dart:typed_data';

import 'package:file_selector/file_selector.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:sprintf/sprintf.dart';
import 'package:word_list_ui/api.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<StatefulWidget> createState() {
    return HomePageState();
  }
}

const XTypeGroup textTypeGroup = XTypeGroup(
  label: 'text',
  extensions: <String>[
    'txt',
  ],
);

enum CountType {
  wordChainCount(hint: "单词链计数"), // 计算单词文本中可以构成多少个单词链
  maxWordLengthWordChain(hint: "最多单词数量单词链"), // 计算最多单词数量的单词链
  maxAlphabetLengthWordChain(hint: "最多字母单词链"); // 计算字母最多的单词链

  final String hint;

  const CountType({required this.hint});
}

class HomePageState extends State<HomePage> {
  CountType _countType = CountType.wordChainCount;
  String? _beginWith;
  String? _endWith;
  String? _notBeginWith;
  bool _isCycleAllowed = false;
  final Stopwatch _stopwatch = Stopwatch();
  bool _isCalculating = false;
  String? _solution;
  bool _isSolutionOk = false;
  int _soluteTime = 0;
  final TextEditingController _wordsController = TextEditingController();
  final alphabet = ascii
      .decode(List.generate(26, (index) => 0x61 + index, growable: false))
      .split('');

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          Flexible(
            child: Column(children: [
              DropdownButton<CountType>(
                value: _countType,
                items: CountType.values
                    .map((e) => DropdownMenuItem<CountType>(
                          value: e,
                          child: Text(e.hint),
                        ))
                    .toList(),
                onChanged: (t) {
                  setState(() {
                    _countType = t ?? CountType.wordChainCount;
                    _isCycleAllowed &= (_countType != CountType.wordChainCount);
                    _beginWith = null;
                    _endWith = null;
                    _notBeginWith = null;
                  });
                },
                icon: const Icon(Icons.arrow_drop_down_sharp),
                elevation: 16,
                style: const TextStyle(color: Colors.deepPurple),
                underline: Container(
                  height: 2,
                  color: Colors.deepPurpleAccent,
                ),
              ),
              CheckboxListTile(
                enabled: _countType != CountType.wordChainCount,
                title: const Text("允许单词成环"),
                onChanged: (b) {
                  setState(() {
                    _isCycleAllowed = b ?? false;
                  });
                },
                value: _isCycleAllowed,
              ),
              Row(
                children: [
                  const Text("单词链开头字母"),
                  DropdownButton<String>(
                    value: _beginWith,
                    items: _countType != CountType.wordChainCount
                        ? alphabet
                                .map((e) => DropdownMenuItem<String>(
                                    value: e, child: Text(e)))
                                .toList() +
                            [
                              const DropdownMenuItem(
                                  value: null, child: Text("无"))
                            ]
                        : [],
                    onChanged: (t) {
                      setState(() {
                        _beginWith = t;
                      });
                    },
                    hint: const Text("单词链开头字母"),
                    disabledHint: const Text("不支持的选项"),
                    icon: const Icon(Icons.arrow_drop_down_sharp),
                    elevation: 16,
                    style: const TextStyle(color: Colors.deepPurple),
                    underline: Container(
                      height: 2,
                      color: Colors.deepPurpleAccent,
                    ),
                  ),
                  Text(_beginWith != null ? '以$_beginWith作为单词链开头字母' : '未指定')
                ],
              ),
              Row(
                children: [
                  const Text("单词链结尾字母"),
                  DropdownButton<String>(
                    value: _endWith,
                    items: _countType != CountType.wordChainCount
                        ? alphabet
                                .map((e) => DropdownMenuItem<String>(
                                    value: e, child: Text(e)))
                                .toList() +
                            [
                              const DropdownMenuItem(
                                  value: null, child: Text("无"))
                            ]
                        : [],
                    onChanged: (t) {
                      setState(() {
                        _endWith = t;
                      });
                    },
                    hint: const Text("单词链结尾字母"),
                    disabledHint: const Text("不支持的选项"),
                    icon: const Icon(Icons.arrow_drop_down_sharp),
                    elevation: 16,
                    style: const TextStyle(color: Colors.deepPurple),
                    underline: Container(
                      height: 2,
                      color: Colors.deepPurpleAccent,
                    ),
                  ),
                  Text(_endWith != null ? '以$_endWith作为单词链结尾字母' : '未指定')
                ],
              ),
              Row(
                children: [
                  const Text("单词不允许出现的首字母"),
                  DropdownButton<String>(
                    value: _notBeginWith,
                    items: _countType != CountType.wordChainCount
                        ? alphabet
                                .map((e) => DropdownMenuItem<String>(
                                    value: e, child: Text(e)))
                                .toList() +
                            [
                              const DropdownMenuItem(
                                  value: null, child: Text("无"))
                            ]
                        : [],
                    onChanged: (t) {
                      setState(() {
                        _notBeginWith = t;
                      });
                    },
                    hint: const Text("单词不允许出现的首字母"),
                    disabledHint: const Text("不支持的选项"),
                    icon: const Icon(Icons.arrow_drop_down_sharp),
                    elevation: 16,
                    style: const TextStyle(color: Colors.deepPurple),
                    underline: Container(
                      height: 2,
                      color: Colors.deepPurpleAccent,
                    ),
                  ),
                  Text(_notBeginWith != null
                      ? '以$_notBeginWith作为单词不允许出现的首字母'
                      : '未指定')
                ],
              ),
            ]),
          ),
          Flexible(
            child: Column(
              children: [
                SizedBox(
                  height: 198,
                  width: 398,
                  child: Card(
                    child: TextField(
                      expands: true,
                      maxLines: null,
                      controller: _wordsController,
                      decoration: const InputDecoration(
                        labelText: "单词列表",
                        hintText: "输入单词列表",
                        icon: Icon(Icons.text_fields),
                      ),
                    ),
                  ),
                ),
                ElevatedButton(
                    onPressed: () async {
                      final XFile? file = await openFile(
                          acceptedTypeGroups: <XTypeGroup>[textTypeGroup]);
                      var str = await file?.readAsString();
                      setState(() {
                        if (str != null) {
                          _wordsController.text = str;
                        }
                      });
                    },
                    child: const Text("选择单词文件打开")),
                const Divider(),
                const Text("solution:"),
                _isCalculating
                    ? const CircularProgressIndicator()
                    : SizedBox(
                        height: 198,
                        width: 398,
                        child: Card(
                          elevation: 2.0,
                          child: Text(_solution ?? ""),
                        ),
                      ),
                ElevatedButton(
                    onPressed: !_isCalculating
                        ? () async {
                            setState(() {
                              _isCalculating = true;
                              _stopwatch.start();
                              _isSolutionOk = false;
                            });
                            switch (_countType) {
                              case CountType.wordChainCount:
                                try {
                                  var words = await genChainsAll(
                                    _wordsController.text
                                        .split(RegExp(r'([^A-Za-z])+')),
                                  );
                                  setState(() {
                                    _solution =
                                        '${words.length}\n${words.join('\n')}';
                                    _isSolutionOk = true;
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                } catch (e) {
                                  setState(() {
                                    _solution = 'error: ${e.toString()}';
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                }
                                break;
                              case CountType.maxWordLengthWordChain:
                                try {
                                  var words = await genChainWord(
                                      _wordsController.text
                                          .split(RegExp(r'([^A-Za-z])+')),
                                      _beginWith ?? ascii.decode([0x0]),
                                      _endWith ?? ascii.decode([0x0]),
                                      _notBeginWith ?? ascii.decode([0x0]),
                                      _isCycleAllowed);
                                  setState(() {
                                    _solution = words.join('\n');
                                    _isSolutionOk = true;
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                } catch (e) {
                                  setState(() {
                                    _solution = 'error: ${e.toString()}';
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                }

                                break;
                              case CountType.maxAlphabetLengthWordChain:
                                try {
                                  var words = await genChainChar(
                                      _wordsController.text
                                          .split(RegExp(r'([^A-Za-z])+')),
                                      _beginWith ?? ascii.decode([0x0]),
                                      _endWith ?? ascii.decode([0x0]),
                                      _notBeginWith ?? ascii.decode([0x0]),
                                      _isCycleAllowed);
                                  // var words = ['233'];

                                  setState(() {
                                    _solution = words.join('');
                                    _isSolutionOk = true;
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                } catch (e) {
                                  setState(() {
                                    _solution = 'error: ${e.toString()}';
                                    _isCalculating = false;
                                    _stopwatch.stop();
                                    _soluteTime =
                                        _stopwatch.elapsedMilliseconds;
                                    _stopwatch.reset();
                                  });
                                }
                                break;
                            }
                            if (context.mounted) {
                              ScaffoldMessenger.of(context).showSnackBar(
                                  const SnackBar(content: Text("core已返回结果")));
                            }
                          }
                        : null,
                    child: const Text("求解")),
                Row(
                  children: [
                    const Spacer(),
                    ElevatedButton(
                        onPressed: _isSolutionOk
                            ? () async {
                                const String fileName = 'solution.txt';
                                final String? path =
                                    await getSavePath(suggestedName: fileName);
                                if (path == null) {
                                  // Operation was canceled by the user.
                                  return;
                                }
                                final Uint8List fileData =
                                    Uint8List.fromList(_solution!.codeUnits);
                                const String mimeType = 'text/plain';
                                final XFile textFile = XFile.fromData(fileData,
                                    mimeType: mimeType, name: fileName);
                                await textFile.saveTo(path);
                              }
                            : null,
                        child: const Text("选择文件以保存结果")),
                    ElevatedButton(
                        onPressed: () {
                          setState(() {
                            _isSolutionOk = false;
                            _solution = null;
                          });
                          ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(content: Text("已清除结果")));
                        },
                        child: const Text("清除结果")),
                    Spacer()
                  ],
                ),
                // if (_solution != null) Text("core在 $_soluteTime ms内返回答案"),
                if (_solution != null)
                  Builder(builder: (context) {
                    double t = _soluteTime.toDouble() / 1000.0;
                    String s = sprintf("%.2f", [t]);
                    return Text("core在 $s s内返回答案");
                  }),
              ],
            ),
          )
        ],
      ),
    );
  }
}
